package message

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

// Handler 消息处理器
type Handler struct {
	service Service
}

// NewHandler 创建消息处理器
func NewHandler(service Service) *Handler {
	return &Handler{service: service}
}

// GetMessage 获取消息详情
// @Summary 获取消息详情
// @Description 根据ID获取消息详情
// @Tags 消息管理
// @Accept json
// @Produce json
// @Param id path int true "消息ID"
// @Success 200 {object} MessageDTO
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /messages/{id} [get]
func (h *Handler) GetMessage(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
		return
	}

	message, err := h.service.GetMessage(uint(id))
	if err != nil {
		status := http.StatusInternalServerError
		if err == ErrMessageNotFound {
			status = http.StatusNotFound
		}
		c.JSON(status, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, message)
}

// CreateMessage 创建消息
// @Summary 创建消息
// @Description 创建新消息并发送给指定接收者
// @Tags 消息管理
// @Accept json
// @Produce json
// @Param message body CreateMessageRequest true "消息信息"
// @Success 201 {object} MessageDTO
// @Failure 400 {object} map[string]interface{}
// @Router /messages [post]
func (h *Handler) CreateMessage(c *gin.Context) {
	var req CreateMessageRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	message, err := h.service.CreateMessage(&req)
	if err != nil {
		status := http.StatusInternalServerError
		if err == ErrInvalidMessageType {
			status = http.StatusBadRequest
		}
		c.JSON(status, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, message)
}

// UpdateMessage 更新消息
// @Summary 更新消息
// @Description 更新现有消息的内容
// @Tags 消息管理
// @Accept json
// @Produce json
// @Param id path int true "消息ID"
// @Param message body UpdateMessageRequest true "消息信息"
// @Success 200 {object} MessageDTO
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /messages/{id} [put]
func (h *Handler) UpdateMessage(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
		return
	}

	var req UpdateMessageRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	message, err := h.service.UpdateMessage(uint(id), &req)
	if err != nil {
		status := http.StatusInternalServerError
		if err == ErrMessageNotFound {
			status = http.StatusNotFound
		}
		c.JSON(status, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, message)
}

// DeleteMessage 删除消息
// @Summary 删除消息
// @Description 删除指定消息
// @Tags 消息管理
// @Accept json
// @Produce json
// @Param id path int true "消息ID"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Failure 403 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /messages/{id} [delete]
func (h *Handler) DeleteMessage(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
		return
	}

	// 从上下文中获取当前用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
		return
	}

	if err := h.service.DeleteMessage(uint(id), userID.(uint)); err != nil {
		status := http.StatusInternalServerError
		switch err {
		case ErrMessageNotFound:
			status = http.StatusNotFound
		case ErrNoPermission:
			status = http.StatusForbidden
		}
		c.JSON(status, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}

// ListMessages 查询消息列表
// @Summary 查询消息列表
// @Description 分页查询消息列表
// @Tags 消息管理
// @Accept json
// @Produce json
// @Param tenant_id query int false "租户ID"
// @Param sender_id query int false "发送者ID"
// @Param type query int false "消息类型"
// @Param title query string false "标题关键字"
// @Param page_num query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} map[string]interface{}
// @Router /messages [get]
func (h *Handler) ListMessages(c *gin.Context) {
	query := &MessageQuery{
		PageNum:  1,
		PageSize: 10,
	}

	// 解析查询参数
	if tenantID, err := strconv.ParseUint(c.Query("tenant_id"), 10, 32); err == nil {
		query.TenantID = uint(tenantID)
	}

	if senderID, err := strconv.ParseUint(c.Query("sender_id"), 10, 32); err == nil {
		query.SenderID = uint(senderID)
	}

	if typeStr := c.Query("type"); typeStr != "" {
		if typeVal, err := strconv.Atoi(typeStr); err == nil {
			query.Type = &typeVal
		}
	}

	query.Title = c.Query("title")

	if pageNum, err := strconv.Atoi(c.Query("page_num")); err == nil && pageNum > 0 {
		query.PageNum = pageNum
	}

	if pageSize, err := strconv.Atoi(c.Query("page_size")); err == nil && pageSize > 0 {
		query.PageSize = pageSize
	}

	messages, total, err := h.service.ListMessages(query)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"total": total,
		"items": messages,
	})
}

// GetUserMessages 获取用户消息列表
// @Summary 获取用户消息列表
// @Description 分页查询用户的消息列表
// @Tags 用户消息
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Param tenant_id query int false "租户ID"
// @Param status query int false "消息状态"
// @Param type query int false "消息类型"
// @Param title query string false "标题关键字"
// @Param page_num query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} map[string]interface{}
// @Router /users/{user_id}/messages [get]
func (h *Handler) GetUserMessages(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	query := &UserMessageQuery{
		ReceiverID: uint(userID),
		PageNum:    1,
		PageSize:   10,
	}

	// 解析查询参数
	if tenantID, err := strconv.ParseUint(c.Query("tenant_id"), 10, 32); err == nil {
		query.TenantID = uint(tenantID)
	}

	if statusStr := c.Query("status"); statusStr != "" {
		if statusVal, err := strconv.Atoi(statusStr); err == nil {
			query.Status = &statusVal
		}
	}

	if typeStr := c.Query("type"); typeStr != "" {
		if typeVal, err := strconv.Atoi(typeStr); err == nil {
			query.Type = &typeVal
		}
	}

	query.Title = c.Query("title")

	if pageNum, err := strconv.Atoi(c.Query("page_num")); err == nil && pageNum > 0 {
		query.PageNum = pageNum
	}

	if pageSize, err := strconv.Atoi(c.Query("page_size")); err == nil && pageSize > 0 {
		query.PageSize = pageSize
	}

	messages, total, err := h.service.GetUserMessages(uint(userID), query)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"total": total,
		"items": messages,
	})
}

// ReadMessage 标记消息为已读
// @Summary 标记消息为已读
// @Description 将指定消息标记为已读状态
// @Tags 用户消息
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Param message_id path int true "消息ID"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Router /users/{user_id}/messages/{message_id}/read [post]
func (h *Handler) ReadMessage(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	messageID, err := strconv.ParseUint(c.Param("message_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的消息ID"})
		return
	}

	if err := h.service.ReadMessage(uint(userID), uint(messageID)); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}

// BatchReadMessages 批量标记消息为已读
// @Summary 批量标记消息为已读
// @Description 将多个消息标记为已读状态
// @Tags 用户消息
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Param request body map[string][]uint true "消息ID列表"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Router /users/{user_id}/messages/batch-read [post]
func (h *Handler) BatchReadMessages(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	var req struct {
		MessageIDs []uint `json:"message_ids" binding:"required,min=1"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.service.BatchReadMessages(uint(userID), req.MessageIDs); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}

// DeleteUserMessage 删除用户消息
// @Summary 删除用户消息
// @Description 将指定消息标记为删除状态（对用户不可见）
// @Tags 用户消息
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Param message_id path int true "消息ID"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Router /users/{user_id}/messages/{message_id} [delete]
func (h *Handler) DeleteUserMessage(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	messageID, err := strconv.ParseUint(c.Param("message_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的消息ID"})
		return
	}

	if err := h.service.DeleteUserMessage(uint(userID), uint(messageID)); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}

// BatchDeleteUserMessages 批量删除用户消息
// @Summary 批量删除用户消息
// @Description 将多个消息标记为删除状态
// @Tags 用户消息
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Param request body map[string][]uint true "消息ID列表"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Router /users/{user_id}/messages/batch-delete [post]
func (h *Handler) BatchDeleteUserMessages(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	var req struct {
		MessageIDs []uint `json:"message_ids" binding:"required,min=1"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.service.BatchDeleteUserMessages(uint(userID), req.MessageIDs); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}

// CountUnreadMessages 统计未读消息数量
// @Summary 统计未读消息数量
// @Description 获取用户未读消息数量
// @Tags 用户消息
// @Accept json
// @Produce json
// @Param user_id path int true "用户ID"
// @Success 200 {object} map[string]int64
// @Failure 400 {object} map[string]interface{}
// @Router /users/{user_id}/messages/unread-count [get]
func (h *Handler) CountUnreadMessages(c *gin.Context) {
	userID, err := strconv.ParseUint(c.Param("user_id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	count, err := h.service.CountUnreadMessages(uint(userID))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"count": count})
}

// SendSystemNotification 发送系统通知
// @Summary 发送系统通知
// @Description 发送系统通知给指定用户
// @Tags 系统通知
// @Accept json
// @Produce json
// @Param notification body SystemNotificationRequest true "通知信息"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Router /notifications/system [post]
func (h *Handler) SendSystemNotification(c *gin.Context) {
	var req SystemNotificationRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.service.SendSystemNotification(&req); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}

// SendAnnouncement 发送公告
// @Summary 发送公告
// @Description 发送公告给指定用户
// @Tags 系统通知
// @Accept json
// @Produce json
// @Param announcement body AnnouncementRequest true "公告信息"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]interface{}
// @Router /notifications/announcement [post]
func (h *Handler) SendAnnouncement(c *gin.Context) {
	var req AnnouncementRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.service.SendAnnouncement(&req); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Status(http.StatusNoContent)
}
